#include <asm-xen/evtchn.h>
#include <asm-xen/xencons.h>
-#include "xencons_ring.h"
/*
* Modes:
* 'xencons=off' [XC_OFF]: Console is disabled.
if (xen_start_info->flags & SIF_INITDOMAIN)
return;
-
/* Spin until console data is flushed through to the daemon. */
while (wc != wp) {
int sent = 0;
static int xencons_priv_irq;
static char x_char;
-/* Non-privileged receive callback. */
-static void xencons_rx(char *buf, unsigned len, struct pt_regs *regs)
+void xencons_rx(char *buf, unsigned len, struct pt_regs *regs)
{
int i;
unsigned long flags;
spin_unlock_irqrestore(&xencons_lock, flags);
}
-/* Privileged and non-privileged transmit worker. */
static void __xencons_tx_flush(void)
{
- int sz, work_done = 0;
+ int sent, sz, work_done = 0;
if (xen_start_info->flags & SIF_INITDOMAIN) {
if (x_char) {
}
while (wc != wp) {
- int sent;
sz = wp - wc;
if (sz > (wbuf_size - WBUF_MASK(wc)))
sz = wbuf_size - WBUF_MASK(wc);
sent = xencons_ring_send(&wbuf[WBUF_MASK(wc)], sz);
- if (sent > 0) {
- wc += sent;
- work_done = 1;
- }
+ if (sent == 0)
+ break;
+ wc += sent;
+ work_done = 1;
}
}
- if (work_done && (xencons_tty != NULL))
- {
+ if (work_done && (xencons_tty != NULL)) {
wake_up_interruptible(&xencons_tty->write_wait);
if ((xencons_tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
(xencons_tty->ldisc.write_wakeup != NULL))
}
}
-/* Privileged receive callback and transmit kicker. */
-static irqreturn_t xencons_priv_interrupt(int irq, void *dev_id,
- struct pt_regs *regs)
+void xencons_tx(void)
{
- static char rbuf[16];
- int i, l;
unsigned long flags;
spin_lock_irqsave(&xencons_lock, flags);
+ __xencons_tx_flush();
+ spin_unlock_irqrestore(&xencons_lock, flags);
+}
- if (xencons_tty != NULL)
- {
- /* Receive work. */
- while ((l = HYPERVISOR_console_io(
- CONSOLEIO_read, 16, rbuf)) > 0)
- for (i = 0; i < l; i++)
- tty_insert_flip_char(xencons_tty, rbuf[i], 0);
- if (xencons_tty->flip.count != 0)
- tty_flip_buffer_push(xencons_tty);
- }
+/* Privileged receive callback and transmit kicker. */
+static irqreturn_t xencons_priv_interrupt(int irq, void *dev_id,
+ struct pt_regs *regs)
+{
+ static char rbuf[16];
+ int l;
- /* Transmit work. */
- __xencons_tx_flush();
+ while ((l = HYPERVISOR_console_io(CONSOLEIO_read, 16, rbuf)) > 0)
+ xencons_rx(rbuf, l, regs);
- spin_unlock_irqrestore(&xencons_lock, flags);
+ xencons_tx();
return IRQ_HANDLED;
}
if ((rc = tty_register_driver(DRV(xencons_driver))) != 0) {
printk("WARNING: Failed to register Xen virtual "
"console driver as '%s%d'\n",
- DRV(xencons_driver)->name, DRV(xencons_driver)->name_base);
+ DRV(xencons_driver)->name,
+ DRV(xencons_driver)->name_base);
put_tty_driver(xencons_driver);
xencons_driver = NULL;
return rc;
"console",
NULL);
BUG_ON(xencons_priv_irq < 0);
- } else {
- xencons_ring_register_receiver(xencons_rx);
}
printk("Xen virtual console successfully installed as %s%d\n",
#include <linux/interrupt.h>
#include <linux/sched.h>
#include <linux/err.h>
-#include "xencons_ring.h"
#include <asm-xen/xen-public/io/console.h>
static int xencons_irq;
-static xencons_receiver_func *xencons_receiver;
static inline struct xencons_interface *xencons_interface(void)
{
BUG_ON((prod - cons) > sizeof(intf->in));
while (cons != prod) {
- if (xencons_receiver != NULL)
- xencons_receiver(
- intf->in + MASK_XENCONS_IDX(cons++, intf->in),
- 1, regs);
+ xencons_rx(intf->in+MASK_XENCONS_IDX(cons,intf->in), 1, regs);
+ cons++;
}
mb();
notify_daemon();
- return IRQ_HANDLED;
-}
+ xencons_tx();
-void xencons_ring_register_receiver(xencons_receiver_func *f)
-{
- xencons_receiver = f;
+ return IRQ_HANDLED;
}
int xencons_ring_init(void)